package com.example.mini_notepad.db;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.example.mini_notepad.R;
import com.example.mini_notepad.util.PropertyConstants;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class NoteDBAdapter {
	private final Context context;
	private NoteDBHelper dbHelper;
	private SQLiteDatabase db;
	
	public NoteDBAdapter(Context ctx){
		this.context = ctx;
		dbHelper = new NoteDBHelper(context);		
	}
	
	public void copyDB(){
		try{
			String destPath = "/data/data/" + context.getPackageName() + "/databases";
			File f = new File(destPath);
			if(!f.exists()){
				f.mkdirs();
				f.createNewFile();
				InputStream inputStream = context.getAssets().open(NoteContracts.DATABASE_NAME);
				OutputStream outputStream = new FileOutputStream(destPath+"/"+NoteContracts.DATABASE_NAME);
				byte[] buffer = new byte[1024];
				int length;
				while((length = inputStream.read(buffer)) > 0){
					outputStream.write(buffer, 0, length);
				}
				inputStream.close();
				outputStream.close();				
			}			
		}catch(FileNotFoundException e){
			Log.w("NoteDBAdapter.copyDB()", "FileNotFoundException occured when construct db.", e);
		}catch(IOException e){
			Log.w("NoteDBAdapter.copyDB()", "IOException occured when construct db.", e);
		}
		
	}
	
	public NoteDBAdapter open() throws SQLException{
		db = dbHelper.getWritableDatabase();
		return this;
	}
	
	public void close(){
		dbHelper.close();
	}
	public long insertNote(NoteEntity entity){
		return insertNote(entity.getTitle(), entity.getContent(), entity.getType(), 
				entity.getCreateTime(), entity.getNotifyTime());
	}
	public long insertNote(String title, String content, short type, String createTime, 
			String notifyTime){
		ContentValues values = new ContentValues();
		values.put(NoteContracts.Note.COLUMN_NAME_TITLE, title);
		values.put(NoteContracts.Note.COLUMN_NAME_CONTENT, content);
		values.put(NoteContracts.Note.COLUMN_NAME_NOTE_TYPE, type);
		values.put(NoteContracts.Note.COLUMN_NAME_CREATE_TIME, createTime);
		values.put(NoteContracts.Note.COLUMN_NAME_NOTIFY_TIME, notifyTime);
		
		return db.insert(NoteContracts.Note.TABLE_NAME, null, values);			
	}
	
	public boolean deleteNote(long rowId){
		int result = db.delete(NoteContracts.Note.TABLE_NAME, 
				NoteContracts.Note._ID + "=" + rowId, null);
		
		return (result > 0);
	}
	
	public List<NoteEntity> getAllNotes(){
		Cursor cursor = db.query(NoteContracts.Note.TABLE_NAME, 
				new String[]{NoteContracts.Note._ID, NoteContracts.Note.COLUMN_NAME_TITLE,
				NoteContracts.Note.COLUMN_NAME_CONTENT, NoteContracts.Note.COLUMN_NAME_NOTE_TYPE,
				NoteContracts.Note.COLUMN_NAME_CREATE_TIME, NoteContracts.Note.COLUMN_NAME_NOTIFY_TIME},
				null, null, null, null, " order by " + NoteContracts.Note.COLUMN_NAME_CREATE_TIME + " DESC");
		List<NoteEntity> entities = new ArrayList<NoteEntity>();
		if(cursor != null){
			cursor.moveToFirst();
			long id;
			String title;
			String content;
			short type;
			String createTime;
			String notifyTime;
			int duration;
			NoteEntity entity;
			do{
				id = cursor.getLong(cursor.getColumnIndex(NoteContracts.Note._ID));
				title = cursor.getString(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_TITLE));
				content = cursor.getString(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_CONTENT));
				type = cursor.getShort(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_NOTE_TYPE));
				createTime = cursor.getString(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_CREATE_TIME));
				notifyTime = cursor.getString(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_NOTIFY_TIME));
				duration = Integer.valueOf(cursor.getString(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_DURATION)));
				entity = new NoteEntity(id, title, content, type, createTime, notifyTime, duration);
				entities.add(entity);				
			}while(cursor.moveToNext());
		}
		
		return entities;
	}
	
	public List<HashMap<String, Object>> getAllNotesForDisplay(){
		Cursor cursor = db.query(NoteContracts.Note.TABLE_NAME, 
				new String[]{NoteContracts.Note._ID, NoteContracts.Note.COLUMN_NAME_TITLE,
				NoteContracts.Note.COLUMN_NAME_CONTENT, NoteContracts.Note.COLUMN_NAME_NOTE_TYPE,
				NoteContracts.Note.COLUMN_NAME_CREATE_TIME, NoteContracts.Note.COLUMN_NAME_NOTIFY_TIME},
				null, null, null, null, NoteContracts.Note.COLUMN_NAME_CREATE_TIME + " DESC");
		//List<NoteEntity> entities = new ArrayList<NoteEntity>();
		List<HashMap<String, Object>> notesList = new ArrayList<HashMap<String, Object>>();
		if(cursor != null){
			cursor.moveToFirst();
			long id;
			String title;
			String content;
			short type;
			String createTime;
			String notifyTime;
			NoteEntity entity;
			do{
				HashMap<String, Object> noteMap = new HashMap<String, Object>();
				id = cursor.getLong(cursor.getColumnIndex(NoteContracts.Note._ID));
				title = cursor.getString(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_TITLE));
				content = cursor.getString(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_CONTENT));
				type = cursor.getShort(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_NOTE_TYPE));
				createTime = cursor.getString(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_CREATE_TIME));
				notifyTime = cursor.getString(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_NOTIFY_TIME));
				noteMap.put("id", id);
				noteMap.put("title", title);
				if(type == PropertyConstants.NOTE_TYPE_TEXT){
					noteMap.put("sub_content", content);
				}
				noteMap.put("tv_notify_time", notifyTime);
				noteMap.put("note_img", (type == PropertyConstants.NOTE_TYPE_TEXT)?R.drawable.txt:R.drawable.rec);
				notesList.add(noteMap);
				//entity = new NoteEntity(id, title, content, type, createTime, notifyTime);
				//entities.add(entity);				
			}while(cursor.moveToNext());
		}
		
		//return entities;
		return notesList;
	}
	
	public int getNumOfNotesInTheSameDay(short type, String title){
		Cursor cursor =
				db.query(true, NoteContracts.Note.TABLE_NAME,
						new String[]{NoteContracts.Note._ID}, NoteContracts.Note.COLUMN_NAME_NOTE_TYPE + "=" + type
						+ " and " + NoteContracts.Note.COLUMN_NAME_TITLE + "=" + title, 
						null, null, null, null, null);
		return cursor.getCount();
	}
	
	public NoteEntity getNote(long rowId){
		Cursor cursor = 
				db.query(true, NoteContracts.Note.TABLE_NAME, 
						new String[]{NoteContracts.Note._ID, NoteContracts.Note.COLUMN_NAME_TITLE,
						NoteContracts.Note.COLUMN_NAME_CONTENT, NoteContracts.Note.COLUMN_NAME_NOTE_TYPE,
						NoteContracts.Note.COLUMN_NAME_CREATE_TIME, NoteContracts.Note.COLUMN_NAME_NOTIFY_TIME},
						NoteContracts.Note._ID + "=" + rowId, null, null, null, null, null);
		if(cursor != null){
			cursor.moveToFirst();
		}
		long id = cursor.getLong(cursor.getColumnIndex(NoteContracts.Note._ID));
		String title = cursor.getString(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_TITLE));
		String content = cursor.getString(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_CONTENT));
		short type = cursor.getShort(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_NOTE_TYPE));
		String createTime = cursor.getString(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_CREATE_TIME));
		String notifyTime = cursor.getString(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_NOTIFY_TIME));
		int duration = Integer.valueOf(cursor.getString(cursor.getColumnIndex(NoteContracts.Note.COLUMN_NAME_DURATION)));
		
		NoteEntity entity = new NoteEntity(id, title, content, type, createTime, notifyTime, duration);
		return entity;
	}
	
	public int updateNotes(short type, String oldTitle, String newTitle){
		ContentValues values = new ContentValues();
		values.put(NoteContracts.Note.COLUMN_NAME_TITLE, newTitle);
		return db.update(NoteContracts.Note.TABLE_NAME, values,
				NoteContracts.Note.COLUMN_NAME_NOTE_TYPE + "=" + type
				+ " and " + NoteContracts.Note.COLUMN_NAME_TITLE + "=" + oldTitle, null);
		
	}
	public int updateNotes(String[] keys, String[] values, String[] whereKeys, String[] whereArgs){
		if(keys == null || values == null || whereKeys == null || whereArgs == null
				|| keys.length != values.length || whereKeys.length != whereArgs.length){
			return -1;
		}
		String whereClause = "";
		for(int i=0;i<whereKeys.length-1;i++){
			whereClause += whereKeys[i] + "=?, ";
		}
		whereClause += whereKeys[whereKeys.length-1] + "=?";
		ContentValues contents = new ContentValues();
		for(int j=0;j<keys.length;j++){
			contents.put(keys[j], values[j]);
		}
		return db.update(NoteContracts.Note.TABLE_NAME, contents, whereClause, whereArgs);		
	}
	
	public boolean updateNote(long rowId, String title, String content, String createTime, String notifyTime){
		ContentValues values = new ContentValues();
		values.put(NoteContracts.Note.COLUMN_NAME_TITLE, title);
		values.put(NoteContracts.Note.COLUMN_NAME_CONTENT, content);		
		values.put(NoteContracts.Note.COLUMN_NAME_CREATE_TIME, createTime);
		values.put(NoteContracts.Note.COLUMN_NAME_NOTIFY_TIME, notifyTime);
		return db.update(NoteContracts.Note.TABLE_NAME, values, 
				NoteContracts.Note._ID + "=" + rowId, null) > 0;
	}

}
